﻿using AutoMapper;
using Azure.Core;
using MediatR;
using ProduceBasicData.Api.Application.Command.ProductionManage.Technology;
using ProduceBasicData.Api.Services;
using ProduceBasicData.Domain.Material;
using ProduceBasicData.Domain.ProductionManage;
using ProduceBasicData.Domain.WarehouseManage;
using ProduceBasicData.Domain.WarehouseManage.WarehouseEnum;
using ProduceBasicData.ErrorCode;
using ProduceBasicData.Infrastructure.Interface;
using ProduceBasicData.Infrastructure;
using System.Diagnostics;

namespace ProduceBasicData.Api.Application.Handler.ProductionManage.Technology
{
    /// <summary>
    /// 工艺结束处理器 - 完成工单并生成入库单
    /// </summary>
    public class EndTechnologyCommandHandler : IRequestHandler<EndTechnologyCommand, ApiResult<int>>
    {
        private readonly IBaseRespository<Work_order> _workOrderRepository;
        private readonly IBaseRespository<StockInOrder> _stockInOrderRepository;
        private readonly IBaseRespository<StockInOrderItem> _stockInOrderItemRepository;
        private readonly IBaseRespository<ProductMaterialModel> _productMaterialRepository;
        private readonly IBaseRespository<Warehouse> _warehouse;
        private readonly ICodeRuleService _codeRuleService;
        private readonly IMapper _mapper;
        private readonly MyDBContext _dbContext;

        public EndTechnologyCommandHandler(
            IBaseRespository<Work_order> workOrderRepository,
            IBaseRespository<StockInOrder> stockInOrderRepository,
            IBaseRespository<StockInOrderItem> stockInOrderItemRepository,
            IBaseRespository<ProductMaterialModel> productMaterialRepository,
            ICodeRuleService codeRuleService,
            IMapper mapper,
            IBaseRespository<Warehouse> warehouse,
            MyDBContext dbContext)
        {
            _workOrderRepository = workOrderRepository;
            _stockInOrderRepository = stockInOrderRepository;
            _stockInOrderItemRepository = stockInOrderItemRepository;
            _productMaterialRepository = productMaterialRepository;
            _codeRuleService = codeRuleService;
            _mapper = mapper;
            _warehouse = warehouse;
            _dbContext = dbContext;
        }

        public async Task<ApiResult<int>> Handle(EndTechnologyCommand request, CancellationToken cancellationToken)
        {
            var result = new ApiResult<int>
            {
                Code = ApiEnum.Success,
                Msg = "工艺结束处理成功"
            };

            // 开启数据库事务
            using var transaction = await _dbContext.Database.BeginTransactionAsync(cancellationToken);
            
            try
            {
                // 1. 根据工单编号获取工单信息
                Work_order workOrder = new Work_order();
                var workOrders = await _workOrderRepository.GetAllAsync();
                workOrder = workOrders.FirstOrDefault(w => w.Id == request.OrderId);

                if (workOrder == null)
                {
                    result.Code = ApiEnum.Failed;
                    result.Msg = "未找到对应的工单信息";
                    return result;
                }

                // 2. 检查工单状态是否可以结束
                if (workOrder.Status == 4) // 已完成
                {
                    result.Code = ApiEnum.Failed;
                    result.Msg = "工单已完成，无需重复操作";
                    return result;
                }

                var currentTime = DateTime.Now;

                // 3. 创建入库单
                var stockInOrder = new StockInOrder
                {
                    InType = StockInType.Production, // 生产入库
                    RelatedOrderNumber = workOrder.Order_no, // 关联工单编号
                    WarehouseId = request.WarehouseId, // 默认仓库，可根据需要调整
                    Status = StockInStatus.Completed, // 直接设为已完成
                    ExpectedInDate = currentTime,
                    ActualInDate = currentTime,
                    Remark = $"工单 {workOrder.Order_no} 生产完成自动生成",
                    CreateName = request.CreateName,
                    CreateTime = currentTime
                };

                // 使用自动编码生成规则
                var autoGeneratedCode = await _codeRuleService.AutoGenerateCodeAsync("ProduceBasicData.Domain.WarehouseManage.StockInOrder");
                if (!string.IsNullOrEmpty(autoGeneratedCode))
                {
                    stockInOrder.OrderNumber = autoGeneratedCode;
                }
                else
                {
                    // 如果没有配置规则，使用默认生成方式
                    stockInOrder.OrderNumber = $"IN{DateTime.Now:yyyyMMddHHmmss}";
                }

                var stockInOrderId = await _stockInOrderRepository.AddAsync(stockInOrder);

                // 4. 更新仓库库存数量
                var warehouse = await _warehouse.GetModelAsync(stockInOrder.WarehouseId);
                if (warehouse != null)
                {
                    warehouse.Capacity += workOrder.Order_number;
                    await _warehouse.Update(warehouse);
                }

                // 5. 创建入库单明细项
                StockInOrderItem stockInOrderItem;
                try
                {
                    stockInOrderItem = new StockInOrderItem
                    {
                        StockInOrderId = stockInOrder.Id,
                        MaterialId = workOrder.Product_id,
                        Unit = "PCS", // 默认单位，可根据实际情况调整
                        PlannedQuantity = workOrder.Order_number, // 计划数量等于工单数量
                        ActualQuantity = workOrder.Order_number, // 实际数量等于工单数量
                        BatchNumber = $"BATCH_{DateTime.Now:yyyyMMddHHmmss}",
                        ProductionDate = currentTime,
                        ExpirationDate = currentTime.AddYears(1), // 默认有效期1年
                        TargetLocationId = request.TargetLocationId, // 默认库位
                        TargetLocationCode = request.LocationCode, // 默认库位编码
                        Remark = $"工单 {workOrder.Order_no} 生产完成入库",
                        CreateName = request.CreateName,
                        CreateTime = currentTime
                    };

                    // 生成入库明细系统编码
                    var autoGeneratedCode2 = await _codeRuleService.AutoGenerateCodeAsync("ProduceBasicData.Domain.WarehouseManage.StockInOrderItem");
                    if (!string.IsNullOrEmpty(autoGeneratedCode2))
                    {
                        stockInOrderItem.SytemNo = autoGeneratedCode2;
                    }
                    else
                    {
                        // 如果没有配置规则，使用默认生成方式
                        stockInOrderItem.SytemNo = $"INT{DateTime.Now:yyyyMMddHHmmss}";
                    }
                }
                catch (Exception ex)
                {
                    Debug.WriteLine($"创建入库明细失败: {ex.Message}");

                    // 如果获取产品信息失败，使用默认值
                    stockInOrderItem = new StockInOrderItem
                    {
                        StockInOrderId = stockInOrderId,
                        MaterialId = workOrder.Product_id,
                        MaterialCode = $"PROD_{workOrder.Product_id}",
                        MaterialName = "生产产品",
                        Specification = "标准规格",
                        Unit = "PCS",
                        PlannedQuantity = workOrder.Order_number,
                        ActualQuantity = workOrder.Order_number,
                        BatchNumber = $"BATCH_{DateTime.Now:yyyyMMddHHmmss}",
                        ProductionDate = currentTime,
                        ExpirationDate = currentTime.AddYears(1),
                        TargetLocationId = 1,
                        TargetLocationCode = "A001",
                        Remark = $"工单 {workOrder.Order_no} 生产完成入库",
                        CreateName = "系统",
                        CreateTime = currentTime
                    };
                }

                var stockInOrderItemId = await _stockInOrderItemRepository.AddAsync(stockInOrderItem);

                // 6. 更新工单状态为已完成
                workOrder.Status = 4; // 已完成
                workOrder.UpdateName = "系统";
                workOrder.UpdateTime = currentTime;

                await _workOrderRepository.Update(workOrder);

                // 提交事务
                await transaction.CommitAsync(cancellationToken);

                result.Data = stockInOrderId;
                result.Msg = $"工艺结束处理成功，生成入库单：{stockInOrder.OrderNumber}";

                Debug.WriteLine($"工单 {workOrder.Order_no} 已完成，生成入库单 {stockInOrder.OrderNumber}");
            }
            catch (Exception ex)
            {
                // 回滚事务
                await transaction.RollbackAsync(cancellationToken);
                
                result.Code = ApiEnum.Failed;
                result.Msg = $"工艺结束处理失败: {ex.Message}";
                result.Data = 0;
                Debug.WriteLine($"工艺结束处理异常: {ex}");
                Debug.WriteLine("事务已回滚");
            }

            return result;
        }

    }
}
